home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
windownt
/
cxxp4w.zip
/
CHAP05
/
WINDOW.CPP
Wrap
C/C++ Source or Header
|
1993-03-11
|
11KB
|
407 lines
#include "window.hpp"
#include "control.hpp"
ATOM aProp, aPropHigh;
#if defined( PTR16) || defined (WIN32)
#define PUTPWIN(hWnd,this) \
SetProp(hWnd,(LPSTR)MAKELONG(aProp,0),(HANDLE)this)
#define GETPWIN(hWnd) \
(Window *)GetProp(hWnd,(LPSTR)MAKELONG(aProp,0))
#define DELPWIN(hWnd) \
(Window *)RemoveProp(hWnd,(LPSTR)MAKELONG(aProp,0))
#else
#define PUTPWIN(hWnd,this)\
SetProp(hWnd,(LPSTR)MAKELONG(aProp,0),(HANDLE)this);\
SetProp(hWnd,(LPSTR)MAKELONG(aPropHigh,0),\
(HANDLE)((DWORD)this >>16))
#define GETPWIN(hWnd) (Window *)\
((DWORD)GetProp(hWnd,(LPSTR)MAKELONG(aProp,0))|\
((DWORD)GetProp(hWnd,(LPSTR)MAKELONG(aPropHigh,0)) <<16))
#define DELPWIN(hWnd) (Window *)\
((DWORD)RemoveProp(hWnd,(LPSTR)MAKELONG(aProp,0))|\
((DWORD)RemoveProp(hWnd,(LPSTR)MAKELONG(aPropHigh,0)) <<16))
#endif // PTR16
// Routines to associate instance pointers with windows
void PutWin(HWND hWnd, Window * pWin) { PUTPWIN(hWnd,pWin);};
Window * GetWin(HWND hWnd) {return GETPWIN(hWnd);};
Window* DelWin(HWND hWnd) {return DELPWIN(hWnd);};
//#ifdef WIN32
// WNDPROC Window::Handler;
//#else
FARPROC Window::Handler; // proc instance for CPPWinProc
//#endif
HANDLE Window::hAccel; // Current accelerator table
// Set window message proc to CPPWinProc
void Window::SetHandler()
{
//#ifdef WIN32
// DefaultHandler = (WNDPROC) GetWindowLong(hWnd,GWL_WNDPROC);
//#else
DefaultHandler = (FARPROC) GetWindowLong(hWnd,GWL_WNDPROC);
//#endif
SetWindowLong(hWnd,GWL_WNDPROC,(LONG) Handler);
PUTPWIN(hWnd,(HANDLE) this);
}
// Create a window
void Window::Create(LPSTR caption, LONG style, int x, int y,
int width, int height, HWND hPwnd, HMENU hMenu)
{
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = (WNDPROC) DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = 0;
hWnd = CreateWindow(Register(wc),
caption,style,x,y,width,height,
hPwnd,hMenu,hInst,NULL);
if (!hWnd) Error(IDS_APPLERROR, (LPSTR)"Window Creation");
SetHandler();
}
Window::Window() {
hWnd=0;
HorzScrollBar=VertScrollBar=NULL;
if (!Handler) {
#ifdef WIN32
Handler = (FARPROC)CPPWinProc;
#else
Handler = MakeProcInstance((FARPROC)CPPWinProc, hInst);
#endif
aProp=AddAtom("pWindow");
aPropHigh=AddAtom("pWindowHigh");
}
}
LPSTR Window::Register(WNDCLASS& wc) {
Error(IDS_APPLERROR,(LPSTR)"No Register method");
return NULL;
}
Window::~Window()
{
if (HorzScrollBar) delete HorzScrollBar;
if (VertScrollBar) delete VertScrollBar;
if (hWnd) {
Show(SW_HIDE);
//Destroy instances associated with child windows
HWND hCwnd= GetWindow (hWnd, GW_CHILD);
while ( hCwnd ){
Window * pWin=(Window*) GETPWIN(hCwnd);
do {
hCwnd=GetWindow(hCwnd,GW_HWNDNEXT);
} while (hCwnd && GetParent(hCwnd)!=hWnd);
if (pWin) delete pWin;
}
if (DELPWIN(hWnd) && DefaultHandler)
SetWindowLong(hWnd,GWL_WNDPROC,(LONG) DefaultHandler);
//if this is the top level window quit the application
if (!GetParent(hWnd)) PostQuitMessage(0);
DestroyWindow(hWnd);
hWnd=0;
}
}
// The application message loop
int Window::MessageLoop()
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
if( msg.message >=WM_KEYFIRST
&& msg.message <=WM_KEYLAST) {
Window * pWin=GETPWIN(GetParent(msg.hwnd));
if (pWin && pWin->DialogMessage(msg)) continue;
}
if (!hAccel ||
!TranslateAccelerator (hWnd, hAccel, &msg)){
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
return msg.wParam;
}
// The window message function, translates messages
// to calls to virtual functions
LONG Window::MessageProc( HWND hWnd, UINT msg, Event& evt)
{
POINT Pt;
switch (msg){
case WM_QUERYENDSESSION:
// OK to end Windows session?
return QueryClose();
case WM_CLOSE:
// if OK delete this instance
if (QueryClose ()) delete this;
return TRUE;
case WM_DESTROY:
if (DELPWIN(hWnd) && DefaultHandler)
SetWindowLong(hWnd,GWL_WNDPROC,(LONG) DefaultHandler);
Window::hWnd=0;
delete this;
break;
case WM_INITMENU:
return InitMenu((HMENU)evt.wParam);
case WM_SIZE:
return Size(LOWORD(evt.lParam),
HIWORD(evt.lParam),evt.wParam);
case WM_PAINT:
return Paint();
case WM_SETFOCUS:
return SetFocus((HWND)evt.wParam);
case WM_KILLFOCUS:
return KillFocus((HWND)evt.wParam);
case WM_CHAR:
return Char(evt.wParam, LOWORD(evt.lParam));
case WM_KEYDOWN:
if (KeyDown(evt.wParam,
*(KEYCODES*)&evt.lParam)) return TRUE;
if (VertScrollBar &&
VertScrollBar->KeyDown(evt.wParam,
*(KEYCODES*)&evt.lParam)) return TRUE;
if (HorzScrollBar &&
HorzScrollBar->KeyDown(evt.wParam,
*(KEYCODES*)&evt.lParam)) return TRUE;
return FALSE;
case WM_LBUTTONDOWN:
Pt.x=LOWORD(evt.lParam); Pt.y=HIWORD(evt.lParam);
return LButtonDown(Pt, evt.wParam);
case WM_LBUTTONUP:
Pt.x=LOWORD(evt.lParam); Pt.y=HIWORD(evt.lParam);
return LButtonUp(Pt, evt.wParam);
case WM_LBUTTONDBLCLK:
Pt.x=LOWORD(evt.lParam); Pt.y=HIWORD(evt.lParam);
return LButtonDblClk(Pt, evt.wParam);
case WM_RBUTTONDOWN:
Pt.x=LOWORD(evt.lParam); Pt.y=HIWORD(evt.lParam);
return RButtonDown(Pt, evt.wParam);
case WM_RBUTTONUP:
Pt.x=LOWORD(evt.lParam); Pt.y=HIWORD(evt.lParam);
return RButtonUp(Pt, evt.wParam);
case WM_MOUSEMOVE:
Pt.x=LOWORD(evt.lParam); Pt.y=HIWORD(evt.lParam);
return MouseMove(Pt, evt.wParam);
case WM_MOUSEACTIVATE:
MouseActivate((HWND)evt.wParam, LOWORD(evt.lParam));
if(DefaultHandler)
return CallWindowProc (DefaultHandler,
hWnd, msg, evt.wParam, evt.lParam);
else return FALSE;
case WM_COMMAND:
{
WORD wNotifyCode; // notification code
WORD wID; // item, control, or accelerator ID
HWND hWndCtl; // handle of control
#ifdef WIN32
wNotifyCode = HIWORD(evt.wParam);
wID = LOWORD(evt.wParam);
hWndCtl = (HWND) evt.lParam;
#else
wID = (int) evt.wParam;
hWndCtl = (HWND) LOWORD(evt.lParam);
wNotifyCode = HIWORD(evt.lParam);
#endif
if (hWndCtl) {
// if message is from a control, call the control method
Control * pControl =
(Control*) (void*)GETPWIN(hWndCtl);
if (pControl)
return pControl->CodeHandler(wNotifyCode);
}
return Command(wID,wNotifyCode, hWndCtl);
}
case WM_DRAWITEM:
{
// Call DrawItem method in control
Control * pControl=
(Control*) (void*)GETPWIN((HWND)
(((DRAWITEMSTRUCT FAR *) evt.lParam)->hwndItem));
if (pControl)
pControl->DrawItem((DRAWITEMSTRUCT FAR * )evt.lParam);
break;
}
#ifdef WIN32
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG:
case WM_CTLCOLORSCROLLBAR:
case WM_CTLCOLORSTATIC:
#else
case WM_CTLCOLOR:
#endif
{
// Call CtlColor method in control
Control * pControl=
(Control*) (void*)GETPWIN((HWND)evt.lParam);
HBRUSH Brush=NULL;
if (pControl) Brush=pControl->CtlColor((HDC)evt.wParam);
if (Brush) return (LONG)Brush;
if(DefaultHandler)
return CallWindowProc (DefaultHandler,
hWnd, msg, evt.wParam, evt.lParam);
else return FALSE;
}
case WM_MEASUREITEM:
{
// Call MeasureItem method in control
MEASUREITEMSTRUCT FAR * pMs=
(MEASUREITEMSTRUCT FAR *)evt.lParam;
Control * pControl=
(Control*) (void*)GETPWIN(GetDlgItem(hWnd,pMs->CtlID));
if (pControl) pControl->MeasureItem(pMs);
else {
pMs->itemHeight=ItemMeasurement::itemHeight;
pMs->itemWidth=ItemMeasurement::itemWidth;
}
break;
}
case WM_HSCROLL:
{
HWND hCtl;
WORD nPos;
#ifdef WIN32
hCtl=(HWND)evt.lParam;
nPos=HIWORD(evt.wParam);
#else
hCtl=(HWND)HIWORD(evt.lParam);
nPos=LOWORD(evt.lParam);
#endif
if (hCtl){
Control * pScroll=
(Control *)(void*)GETPWIN(hCtl);
if (pScroll)
pScroll->CodeHandler((WORD)evt.wParam,nPos);
}
else if (HorzScrollBar){
((Control *)(void*)HorzScrollBar)
->CodeHandler((WORD)evt.wParam,nPos);
}
break;
}
case WM_VSCROLL:
{
HWND hCtl;
WORD nPos;
#ifdef WIN32
hCtl=(HWND)evt.lParam;
nPos=HIWORD(evt.wParam);
#else
hCtl=(HWND)HIWORD(evt.lParam);
nPos=LOWORD(evt.lParam);
#endif
if (hCtl){
Control * pScroll=
(Control *)(void*)GETPWIN(hCtl);
if (pScroll)
pScroll->CodeHandler((WORD)evt.wParam,nPos);
}
else if (VertScrollBar){
((Control *)(void*)VertScrollBar)
->CodeHandler((WORD)evt.wParam,nPos);
}
break;
}
default:
if (DefaultHandler)
return CallWindowProc (DefaultHandler,
hWnd, msg, evt.wParam, evt.lParam);
} // switch
return FALSE;
} // MessageProc
BOOL Window::Size(UINT Width, UINT Height, UINT Type) {
if (!DefaultHandler) return FALSE;
return CallWindowProc (DefaultHandler,
hWnd, WM_SIZE, Type, MAKELONG(Width, Height));
}
BOOL Window::Paint() {
if (!DefaultHandler) return FALSE;
return CallWindowProc (DefaultHandler, hWnd, WM_PAINT, 0,0);
}
BOOL Window::Command( UINT Id, UINT Code, HWND hControl) {
if (!DefaultHandler) return FALSE;
#ifdef WIN32
return CallWindowProc (DefaultHandler,
hWnd, WM_COMMAND, MAKELONG(Id, Code), (DWORD)hControl);
#else
return CallWindowProc (DefaultHandler,
hWnd, WM_COMMAND, Id, MAKELONG(hControl, Code));
#endif
}
LONG CALLBACK CPPWinProc(HWND hWnd, UINT Message,
UINT wParam,LONG lParam)
{
Window* pWin = GETPWIN(hWnd);
Event evt(wParam,lParam);
if (pWin) {
// There is a C++ instance for the window
return pWin->MessageProc(hWnd,Message,evt);
}
else if (Message== WM_MEASUREITEM) {
// return the current owner-draw item size
MEASUREITEMSTRUCT FAR * pMs=
(MEASUREITEMSTRUCT FAR *)lParam;
pMs->itemHeight=ItemMeasurement::itemHeight;
pMs->itemWidth=ItemMeasurement::itemWidth;
return TRUE;
}
else return FALSE;
} // CPPWinProc
void Window::Move(RECT * rc, BOOL repaint) {
MoveWindow (hWnd,
rc->left,
rc->top,
rc->right-rc->left,
rc->bottom-rc->top,
repaint);
}